package edu.westga.cs3152.project2;

import java.util.ArrayList;

/**
 * The SpellingSuggestor takes in list of misspelled words and offers suggestions 
 * as to what words the person that typed them may have meant to type.
 * 
 * @author Lewis Williams
 * @version 2011.3.18
 */
public class SpellingSuggestor {
	
	private ArrayList<String> suggestions = new ArrayList<String>();
	//A dictionary to compare words against 
	private Dictionary dictionary = new Dictionary("words.txt");
	
	/**
	 * A default constructor for SpellingSuggestor that does nothing.
	 */
	public SpellingSuggestor(){}
	
	/**
	 * Runs the three different word suggestion methods on the word 
	 * it is given and returns a list of the generated words.
	 * @param word
	 * 			The misspelled word that suggestions are being generated for.
	 * @return suggestions
	 * 			Suggested alternatives to the misspelled word.
	 */
	public ArrayList<String> getReplacementWords(String word){
		suggestions.clear();
		suggestions.addAll(getRemoveOneLetterSuggestions(word));
		suggestions.addAll(getWordSplitSuggestions(word));
		suggestions.addAll(getSwapAdjacentLettersSuggestions(word));
		
		return suggestions;
	}

	/**
	 * The first replacement suggestion algorithm that removes every letter from 
	 * the word once to see if the error is possibly a simple extra letter.
	 * @param word
	 * 			The misspelled word that suggestions are being generated for.
	 * @return suggestions
	 * 			Suggested alternatives to the misspelled word.		
	 */
	private ArrayList<String> getRemoveOneLetterSuggestions(String word) {
		ArrayList<String> suggestions = new ArrayList<String>();
		for(int i = 0; i < word.length(); i++){
			StringBuilder tempWord = new StringBuilder(word);
			tempWord.deleteCharAt(i);
			if(dictionary.contains(tempWord.toString()) && !this.suggestions.contains(tempWord.toString()) && !suggestions.contains(tempWord.toString())){
				suggestions.add(tempWord.toString());
			}
		}
		return suggestions;
	}
	
	/**
	 * The second replacement suggestion algorithm that splits the 
	 * word into two words to see if the error is a missing space.
	 * @param word
	 * 			The misspelled word that suggestions are being generated for.
	 * @return suggestions
	 * 			Suggested alternatives to the misspelled word.		
	 */
	private ArrayList<String> getWordSplitSuggestions(String word) {
		ArrayList<String> suggestions = new ArrayList<String>();
		for(int i = 0; i < word.length(); i++){
			String tempWord1 = word.substring(0, i);
			String tempWord2 = word.substring(i, word.length());
			if(dictionary.contains(tempWord1) && dictionary.contains(tempWord2) && !this.suggestions.contains(tempWord1 + " " + tempWord2)){
				suggestions.add(tempWord1 + " " + tempWord2);
			}
		}
		return suggestions;
	}
	
	/**
	 * The third replacement suggestion algorithm that swaps all the adjacent letters 
	 * in the word to see if one letter was accidentally hit before the other
	 * @param word
	 * 			The misspelled word that suggestions are being generated for.
	 * @return suggestions
	 * 			Suggested alternatives to the misspelled word.		
	 */
	private ArrayList<String> getSwapAdjacentLettersSuggestions(String word) {
		ArrayList<String> suggestions = new ArrayList<String>();
		String frontOfWord = "";
		String backOfWord = "";
		String suggestedWord = "";
		char letter1;
		char letter2;
		for(int i = 0; i < word.length() - 1; i++){
			letter1 = word.charAt(i);
			letter2 = word.charAt(i + 1);
			if(i != 0 && i != word.length() - 2){
				frontOfWord = word.substring(0, i);
				backOfWord = word.substring(i + 2, word.length());
				suggestedWord = frontOfWord + letter2 + letter1 + backOfWord;
			}
			else if(i == 0){
				suggestedWord = String.valueOf(letter2) + String.valueOf(letter1) + word.substring(i + 2, word.length());
			}
			else if(i == word.length() - 2){
				suggestedWord = word.substring(0, word.length() - 2) + letter2 + letter1;
			}
			if(dictionary.contains(suggestedWord) && !this.suggestions.contains(suggestedWord)){
				suggestions.add(suggestedWord);
			}
		}
		return suggestions;
	}

}
